// Copyright (C) 2025, ZWSOFT Co., LTD.(Guangzhou)
// Licensed under the MIT License. See LICENSE in the project root for license information.

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using TestClient.Domain;

namespace TestClient.ViewModel;
public partial class TangentTestViewModel : PageViewModelBase
{
    [ObservableProperty]
    private string pointId = "";
    [ObservableProperty]
    private string curveId = "";
    [ObservableProperty]
    private string surfaceId = "";
    [ObservableProperty]
    private string inquiredVector = "";

    public IAsyncRelayCommand SelectPointCommand { get; }
    public IAsyncRelayCommand SelectCurveCommand { get; }
    public IAsyncRelayCommand SelectSurfaceCommand { get; }
    public IAsyncRelayCommand InquireCurveCommand { get; }
    public IAsyncRelayCommand InquireSurfaceCommand { get; }
    public IAsyncRelayCommand ClearArrowCommand { get; }

    public TangentTestViewModel(
        VFAdapterWrapper wrapper,
        ISnackNotifyService notifyService) : base(wrapper, notifyService)
    {
        SelectPointCommand = CreateAsyncRpcCommand(SelectPoint);
        SelectCurveCommand = CreateAsyncRpcCommand(SelectCurve);
        SelectSurfaceCommand = CreateAsyncRpcCommand(SelectSurface);
        InquireCurveCommand = CreateAsyncRpcCommand(InquireCurve);
        InquireSurfaceCommand = CreateAsyncRpcCommand(InquireSurface);
        ClearArrowCommand = CreateAsyncRpcCommand(ClearArrow);
    }

    private async Task SelectPoint()
    {
        EnsureConnected();
        PointId = await ViewModelHelpers.SelectEnt(Wrapper, "Point");
    }
    private async Task SelectCurve()
    {
        EnsureConnected();
        CurveId = await ViewModelHelpers.SelectEnt(Wrapper, "Curve");
    }
    private async Task SelectSurface()
    {
        EnsureConnected();
        SurfaceId = await ViewModelHelpers.SelectEnt(Wrapper, "Surface");
    }
    private async Task InquireCurve()
    {
        var vec = await Task.Run(() =>
        {
            var vec = Wrapper.GetUnitTangentVectorAtPoint(CurveId, PointId);
            Wrapper.DisplayArrow(int.Parse(PointId), vec);
            return vec;
        });
        InquiredVector = vec.ToString();
    }
    private async Task InquireSurface()
    {
        var vec = await Task.Run(() =>
        {
            Wrapper.CreateNormalLineAndArrowHead(SurfaceId, PointId);
            return Wrapper.GetUnitNormalVectorAtPoint(SurfaceId, PointId);
        });
        InquiredVector = vec.ToString();
    }
    private async Task ClearArrow()
    {
        await Task.Run(() =>
        {
            Wrapper.DeleteNormalLineAndArrowhead(PointId);
        });
    }
}
